Super Key 는 테이블 내의 특정한 튜플을 식별할 수 있도록하는 어트리뷰트의 집합입니다. 어떤 어트리뷰트의 집합으로 특정한 튜플을 식별하도록 하는 속성이 유일성이고 슈퍼키는 항상 이 유일성을 만족시켜야합니다.
Candiate Key는?
후보키는 슈퍼키가 만족해야하는 유일성 뿐만 아니라 최소성도 만족시켜야 합니다. 최소성이란 슈퍼키에 속하는 어트리뷰트의 집합 내에 튜플을 식별하기 위한 어트리뷰트만 존재하는 키를 의미합니다. 예를 들어 주민등록번호와 이름은 슈퍼키가 될 수 있지만 후보키는 될 수 없습니다. 동명이인이 있을 수 있기 때문입니다.
Primary Key는 어때요?
기본키는 후보 키 중 하나를 선택하여 해당 테이블에서 튜플을 구분하는 기준으로 삼는 키를 의미합니다. 기본키는 NULL 값을 가질 수 없다는 엄격한 규칙이 있습니다.
Alternate Key 는 뭐예요?
여러 후보 키들 중 기본키로 선택되지 않은 나머지 후보키들은 모두 대체 키가 됩니다.
Foreign Key 에 대해서 설명해보세요
외래키는 다른 테이블의 기본키를 참조하는 키입니다. 외래키의 필드 값은 외래키가 참조하는 기본키의 필드값과 동일하거나 NULL 이어야 한다는 규칙이 있습니다.
Join 연산
Natural Join
Natural Join은 두 테이블에서 공통된 속성을 찾아 필드 값이 같은 튜플을 합쳐서 하나의 테이블로 만들어줍니다. Natural Join 은 동일한 자동으로 공통되는 속성을 찾기 때문에 두 테이블의 도메인, 속성값, 필드값이 같아야 한다는 조건이 있습니다.
Inner Join
Inner Join 은 두 테이블 사이에 공통된 속성을 찾아 필드 값이 같은 튜플을 합쳐서 하나의 테이블로 만듭니다. 이때 Join 에 대한 조건을 직접 지정해주어서 지정된 속성과 속성값을 기준으로 테이블을 합치게 됩니다.
Natural Join 과 Inner Join 의 차이를 말해보세요.
Inner Join 은 동일한 속성을 두 테이블의 각각 속한 별개의 속성으로 표시하는 반면에 Natural Join 은 하나의 속성으로 처리합니다.
Outer Join 은 두 테이블을 동일한 속성과 속성값을 기준으로 합치지만 양 테이블에 동일한 값이 없는 튜플도 함께 합쳐줍니다. 이때 값이 없는 필드는 NULL 로 표시합니다.
Outer Join 에는 어떤 종류가 있어요?
Left Join, Right Join, Full Join 이 있습니다.
Left Join 은 왼쪽 테이블에 있는 데이터를 모두 읽은 뒤 좌측 테이블을 읽으며 공통된 속성과 속성값을 가진 튜플을 찾습니다. 따라서 왼쪽 테이블에는 존재하지 않지만 오른쪽 테이블에 존재하는 튜플은 제외됩니다.
Right Join 은 반대로 오른쪽 테이블을 먼저 읽기 때문에 오른쪽 테이블에 존재하지 않는 속성값을 가진 튜플은 왼쪽 테이블에서 합칠 때 제외됩니다.
Full Join 은 두 테이블의 모든 튜플을 합쳐줍니다. 따라서 서로 겹치지 않는 튜플도 제외되지 않고 모두 포함됩니다.
MySQL 에서는 Full Join 을 어떻게 구현하는지 알아요?
MySQL 에서는 Full Join 을 지원하지 않기 때문에 두 테이블을 각각 left join, right join 하고 UNION 으로 합쳐주어야 합니다.
Normalization (정규화)
데이터베이스 이상현상이 무엇인지 설명해보세요.
데이터 이상현상은 데이터베이스 내부에서 발생되는 불일치 현상을 말합니다. 데이터 이상현상에는 3 가지 종류가 있습니다.
갱신 이상은 어떤 데이터를 업데이트할 때 데이터베이스 내부에 중복된 데이터 중 일부만 갱신하여 데이터가 불일치 되는 문제입니다.
삽입 이상은 테이블에 새로운 튜플을 삽입할 때, 특정 속성에 대한 필드 값이 존재하지 않아 불필요한 NULL 값을 삽입하게 되는 문제입니다.
삭제 이상은 테이블에서 어떤 속성값을 삭제하고 싶을 때, 튜플 전체를 삭제하면서 발생하는 문제입니다.
데이터베이스 정규화 방법에 대해서 설명해보세요.
데이터베이스 이상현상을 방지하기 위해 데이터의 중복을 없애는 목적으로 정규화를 사용합니다. 정규화는 1NF 부터 6NF, 그리고 BCNF 가 있습니다.
1NF 는 테이블의 모든 속성이 원자적인 값을 지니게 합니다.
2NF 는 1NF를 만족하며 테이블의 모든 속성이 기본키에 대해 완전 함수적 종속을 만족해야합니다. 완전 함수적 종속이란 기본키를 구성하는 모든 속성을 사용해야 튜플을 특정할 수 있는 것을 말합니다. 기본키의 일부 속성만 사용해서 튜플을 특정할 수 있다면, 2NF에 위배됩니다.
3NF 는 2NF를 만족하며 기본키에 속하지 않는 속성이 이행적 함수 종속을 가지지 않아야합니다. 이행적 함수종속은 어떤 속성 X로 속성 Y를 특정할 수 있을 때 Y로 Z 속성을 특정할 수 있어 X가 Z를 특정할 수 있는 상황을 말합니다. 이때는 X, Y 로 구성된 테이블과 Y, Z 로 구성된 테이블로 분리하여 3NF를 만족시킵니다.
BCNF 는 테이블에 존재하는 모든 결정자가 후보키가 되게 만들어야합니다. 만약 후보키가 될 수 없다면 해당 결정자와 그 결정자와 종속관계에 있는 속성을 따로 분리해주는 것으로 BCNF 정규화를 만족시킬 수 있습니다.
정규화가 반드시 필요하다고 생각해요?
정규화는 데이터 이상현상을 방지하지만 테이블을 여러개로 나누게 되므로 이후에 JOIN 연산을 많이 발생기켜 성능저하의 원인이 될 수 있습니다. 따라서 테이블 사용시에 성능저하가 예상되는 테이블은 의도적으로 정규화를 적용하지 않는 반정규화를 사용하기도 합니다.
트랜잭션
트랜잭션이 무엇인지 말해보세요.
트랜잭션은 데이터베이스의 상태를 변화시키는 작업의 단위입니다.
트랜잭션 보호가 왜 필요한지 말해보세요.
트랜잭션은 다수의 사용자가 데이터베이스의 데이터에 접근할 때 데이터의 무결성을 보장하기 위해서 사용합니다.
트랜잭션의 성질은 어떤게 있어요?
트랜잭션은 네 가지 성질을 가져야합니다. (ACID)
먼저, 원자성은 트랜잭션에 관련된 작업은 모두 다 실행되거나 모두 다 실행되지 않도록 보장되어야하는 것을 의미합니다.
일관성은 트랜잭션이 완료되었을 때, 데이터베이스의 데이터가 일관적인 상태를 유지하도록 해야하는 것을 의미합니다.
격리성은 어떤 트랜잭션이 수행될 때 다른 트랜잭션이 간섭할 수 없게 해야한다는 것을 의미합니다.
지속성은 한번 성공한 트랜잭션은 데이터베이스에 영구적으로 반영되어야 한다는 것을 의미합니다.
그럼 원자성을 보장하는 방법에 대해서 설명해보세요.
트랜잭션의 원자성을 보장하기 위해서 Commit 과 Rollback 을 사용합니다. Commit은 트렌잭션의 작업이 정상적으로 종료되었고 데이터베이스에 적용되었음을 확정합니다. Rollback은 현재까지 진행중이던 트랜잭션 작업을 취소하고 트랜잭션이 시작되기 전 상태로 데이터베이스를 되돌립니다.
일관성은 그럼 어떻게 보장해야겠어요?
일관성은 Trigger를 통해 어떤 작업이 수행될 때 연쇄적으로 다른 작업을 수행하도록 할 수 있습니다. 예를 들어 한 테이블의 튜플을 삭제한다고 했을 때, 외래키에 의해 연결된 테이블이 있다면 해당 테이블의 튜플도 함께 삭제해주는 작업을 Trigger로 지정할 수 있습니다.
격리성이 보장되지 않아 발생하는 이슈를 설명해보세요.
Phantom Read, Nonrepeatable Read, Dirty Read 문제가 있습니다.
Phantom Read 는 한 트랜잭션 안에서 두 번의 읽기 연산이 있을 때, 처음 데이터를 읽은 후 다른 트랜잭션이 새로운 튜플을 데이터베이스에 삽입시켜 한번 더 데이터를 읽을 때 이전에는 없었던 데이터가 새로 생기는 현상을 의미합니다.
Non-Repeatable Read는 어떤 트랜잭션이 데이터를 두 번 조회할 때 처음 조회한 직후에 다른 트랜잭션이 간섭하여 해당 데이터의 값을 업데이트하게 되면, 다음 조회에는 처음과 다른 데이터 값이 조회되는 현상을 의미합니다.
Dirty Read 는 어떤 트랜잭션이 아직 Commit을 하지 않은 상황에서 데이터를 수정하고 다른 트랜잭션이 수정된 데이터를 읽었을 때, 앞선 트랜잭션이 rollback 된다면 데이터베이스에 더 이상 존재하지 않는 데이터를 조회하게 되는 현상을 의미합니다.
트랜잭션 격리 수준에 대해서 설명해보세요.
Level 0 부터 Level 3 까지 있습니다.
Level 0는 Read Uncommited 로 모든 트랜잭션이 제한없이 데이터에 접근할 수 있게하는 격리수준입니다.
Level 1은 Read Committed 로 커밋이 완료된 데이터만 읽도록 합니다.
Level 2은 Repeatable Read 로 한 트랜잭션 안에서 여러번 테이블을 조회해도 같은 테이블을 얻을 수 있게합니다. 이를 위해 해당 트랜잭션이 시작되기 전에 완료된 커밋을 기준으로 데이터를 조회합니다.
Level 3은 Serializable 로 여러 트랜잭션이 병렬적으로 수행되는 것을 허용하지 않습니다.
공유 Lock 과 베타 Lock 에 대해서 설명해보세요.
공유 Lock 은 데이터를 읽을 때 사용하는 Lock 이고 베타 Lock 은 데이터를 변경할 때 사용하는 Lock 입니다. 공유 Lock 으로 인해서 읽기연산은 여러 트랜잭션이 한번에 사용할 수 있습니다. 그리고 베타 Lock 으로 인해 해당 Lock 이 해제될 때까지 다른 트랜잭션이 데이터를 변경하지 못하게 할 수 있습니다.
Lock 을 사용했을 때 단점은 없을까요?
Locking 이 과도하게 사용되면 동시성 문제는 해결되지만 처리시간이 길어진다는 단점이 있습니다.
인덱스
인덱스의 장점과 단점을 말해보세요.
인덱스를 사용하면 테이블을 조회하는 속도가 빨라집니다. 하지만 조회가 아니라 데이터를 변경해야하는 속성에 인덱스를 걸면 오히려 성능이 저하될 수 있습니다.
데이터를 변경하는 속성에 적용하면 왜 성능이 저하되는데요?
삭제, 갱신, 삽입으로 기존 데이터를 변경하거나 새로운 데이터를 추가하게 되면 해당 데이터에 걸려있는 인덱스를 함께 변경하거나 추가해줘야합니다. 따라서 추가적인 연산이 발생하므로 성능이 저하됩니다.
그럼 인덱스는 어떤 상황에서 쓰는게 적합할까요?
데이터의 양이 많지만 조회를 주로하고 중복데이터가 많지 않은 속성에 적용했을 때 좋은 성능을 보장받을 수 있습니다.
인덱스는 내부적으로 어떻게 구현되는지 알아요?
데이터베이스에서는 B+Tree 자료구조를 사용하여 인덱스를 관리합니다. 데이터를 나타내는 각 리프노드들이 인덱스를 가지고 있고 각 리프노드들이 서로 더블링크드리스트로 연결되어 있어 순차적인 탐색을 빠르게 할 수 있습니다.
Clustered Index 와 Non-Clustered Index 의 차이가 뭔가요?
클러스터드 인덱스는 데이터가 추가될 때마다 인덱스를 기준으로 데이터를 재배열합니다. 따라서 데이터가 순차적으로 저장됩니다. 이 때문에 조회의 속도는 빠르지만 갱신, 삽입, 삭제 시 전체 테이블을 다시 재배열 해주어야 하는 오버헤드를 가지고있습니다.
넌 클러스터드 인덱스는 데이터와 인덱스를 따로 분리하여 관리합니다. 따라서 데이터는 물리적으로 정렬하지 않고 정렬된 인덱스가 가르키는 포인터로 데이터를 찾습니다. 따라서 조회에는 클러스터드 인덱스보다 많은 시간이 들지만 갱신, 삭제, 삽입에는 클러스터드 인덱스보다 빠른 성능을 보입니다.
Cardinality 가 뭔지 알아요?
카디널리티는 컬럼 내의 중복되는 데이터의 비율에 따라서 결정됩니다. 어떤 컬럼에 중복되는 데이터가 많다면 카디널리티가 낮다고 할 수 있습니다. 카디널리티를 수치화하면 해당 컬럼에 있는 고유한 데이터의 개수입니다.
그럼 Selectivity도 설명할 수 있어요?
선택도는 카디널리티를 해당 컬럼의 전체 데이터 개수로 나눈 값입니다. 즉, 한 컬럼 내에 고유한 데이터의 비율을 나타냅니다.
인덱스를 설정할 때 카디널리티가 성능에 어떤 영향을 미칠까요?
카디널리티가 높은 인덱스에 인덱스를 설정하면 한 인덱스로 많은 데이터를 필터링할 수 있기 때문에 인덱스가 더 좋은 성능을 내도록 할 수 있습니다.
NoSQL
NoSQL 과 RDBMS 의 차이를 말해보세요
RDBMS 는 스키마를 사용하여 데이터를 저장합니다. 또한 SQL 명령을 통해 구조화된 데이터베이스를 구축할 수 있어 안전하고 트랜잭션을 통해 데이터의 무결성을 보장합니다. 하지만 구조화된만큼 시스템이 복잡해지고 엄격합니다. 반면에 NoSQL은 스키마가 없기 때문에 데이터를 추가하는 것이 자유롭고 확장에 열려있습니다. 하지만 중복데이터에 대한 관리가 RDMS에 비해 복잡하다는 단점이 있습니다.
NoSQL이 확장에 열려있는 이유는 뭔가요?
NoSQL은 데이터를 분산된 서버에 저장하는 분산처리 방식으로 운영됩니다. 따라서 대용량 데이터를 더 쉽게 다룰 수 있습니다.